using System;
using System.Linq;
using System.Threading.Tasks;
using CodeAngel.Domain.Framework;

namespace CodeAngel.Domain.Aggregates
{
    /// <summary>
    /// List of domains
    /// </summary>
	public partial class DomainListAggregate : Aggregate
	{

		#region Root

		public new DomainCollection Root
		{
		    get
		    {
                return base.Root as DomainCollection;
		    }
		}

		#endregion

		#region LoadAsync

        /// <summary>
        /// Instructs this aggregate to asynchronously load its object graph based on the
        /// identified filter.  The currently logged in user (see User.LoggedInUser) will be used
        /// for security related purposes.
        /// </summary>
		public Task LoadAsync(DomainFilter filter)
		{
            return this.LoadAsync(filter, User.LoggedInUser);
		}

        /// <summary>
        /// Instructs this aggregate to asynchronously load its object graph will all entities of
        /// this type.  The currently logged in user (see User.LoggedInUser) will be used for
        /// security related purposes.
        /// </summary>
		public Task LoadAllAsync()
		{
            return this.LoadAsync(new DomainFilter(), User.LoggedInUser);
		}

		#endregion

		#region IsFilterTypeValid

        /// <summary>
        /// Determines if the passed in filter is valid for this aggregate.
        /// </summary>
		protected override bool IsFilterTypeValid(IFilter filter)
		{
            return (filter is DomainFilter);
		}

		#endregion

		#region BuildObjectGraph

        /// <summary>
        /// Provides a way for the developer to custom build the object graph for this aggregate. 
        /// Be sure to set the _BuildObjectGraphIsHandled field to true to avoid having the
        /// auto-generated BuildObjectGraph code executed.
        /// </summary>
		partial void CustomBuildObjectGraph();

        /// <summary>
        /// Informs the auto-generated BuildObjectGraph method that building the object graph has
        /// already been handled and it does not need to do anything.
        /// </summary>
		private bool _BuildObjectGraphIsHandled = false;

        /// <summary>
        ///
        /// </summary>
		protected override void BuildObjectGraph()
		{
            // Offers the developer a way to build the object graph by hand.
            this.CustomBuildObjectGraph();
            if (this._BuildObjectGraphIsHandled) return;
            
            try
            {
            var ThisRoot = new DomainCollection(this);
            foreach (var ThisDomainDto in this.DtoHost.RootDomains)
            {
                var ThisDomain = new Domain(this);
                ThisRoot.Add(ThisDomain);
            ThisDomain.InitializeAllScalarProperties(ThisDomainDto);
            }
            base.Root = ThisRoot;
            }
            catch (Exception ex)
            {
            throw new Exception("There was an unexpected problem building the object graph.  See inner exception for more info.", ex);
            }
		}

		#endregion

		#region SynchronizeDtos

        /// <summary>
        /// Provides a way for the developer to custom synchronize the dtos with the object graph
        /// for this aggregate.  Be sure to set the _SynchronizeDtosIsHandled field to true to
        /// avoid having the auto-generated synchronization code executed.
        /// </summary>
		partial void CustomSynchronizeDtos();

        /// <summary>
        /// Informs the auto-generated SynchronizeDtos method that synchronization has already been
        /// handled and it does not need to do anything.
        /// </summary>
		private bool _SynchronizeDtosIsHandled = false;

        /// <summary>
        ///
        /// </summary>
		protected override void SynchronizeDtos()
		{
            // Offers the developer a way to synchronize the dtos by hand.
            this.CustomSynchronizeDtos();
            if (this._SynchronizeDtosIsHandled) return;
            
            try
            {
            foreach (var ThisDomain in this.Root)
            {
                ThisDomain.SynchronizeDto(this.DtoHost.RootDomains);
            }
            }
                catch (Exception ex)
            {
                throw new Exception("There was an unexpected problem while synchronizing DTOs.  See inner exception for more info.", ex);
            }
		}

		#endregion

		#region UserHasPermissionToSave

        /// <summary>
        /// Identifies if the current user has permission to save all the updateable entities in
        /// this AggregateDefinition.
        /// </summary>
		protected override bool UserHasPermissionToSave()
		{
            return false;
		}

		#endregion

	}
}

